package com.zmn.plat.admin.controller.product.cityratio;

import java.util.*;
import java.util.stream.Collectors;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.util.CollectionUtils;
import org.springframework.web.bind.annotation.ModelAttribute;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestParam;
import org.springframework.web.servlet.ModelAndView;

import com.zmn.common.constant.GlobalConsts;
import com.zmn.common.dictionary.DictModel;
import com.zmn.common.utils.number.NumberUtil;
import com.zmn.plat.common.constant.BaseAreaConsts;
import com.zmn.plat.common.constant.ProductConsts;
import com.zmn.plat.common.dictionary.BaseCityPriceTypeEnum;
import com.zmn.plat.common.dictionary.BaseCityRatioTypeEnum;
import com.zmn.plat.model.entity.area.AreaQuery;
import com.zmn.plat.model.entity.area.BaseArea;
import com.zmn.plat.model.entity.base.city.ratio.BaseCityRatio;
import com.zmn.plat.model.entity.base.city.ratio.BaseCityRatioQuery;
import com.zmn.plat.model.entity.category.BaseCategory;
import com.zmn.plat.model.entity.servcategory.ServCategory;
import com.zmn.plat.model.vo.product.BaseCityCategoryRatioVo;
import com.zmn.plat.model.vo.product.BaseCityRatioVo;

/**
 * 类描述:城市价格系数管理查询控制
 *
 * @author linfeng
 * @since 2019/08/21/11:02
 */
@Controller
@RequestMapping("/product/citypriceratio/")
public class ServCityPriceRatioListController extends ServCityPriceRatioBaseController {
    private Logger logger = LoggerFactory.getLogger(ServCityPriceRatioListController.class);

    /**
     * 描述: 城市价格系数列表
     *
     * @param query
     *            查询实体
     * @return ModelAndView
     */
    @RequestMapping(value = "list")
    public ModelAndView list(@ModelAttribute BaseCityRatioQuery query) {
        ModelAndView mav = new ModelAndView("product/citypriceratio/list");
        if (query.getPriceType() == null) {
            query.setPriceType(BaseCityPriceTypeEnum.PRICE.getCode());
        }
        try {
            List<DictModel> provinces = areaCache.getAreaList(GlobalConsts.TOP_ID);
            List<BaseCityRatioVo> items = baseCityRatioService.listPageByQuery(query);
            mav.addObject("vo", query);
            mav.addObject("provinces", provinces);
            mav.addObject("items", items);
        } catch (Exception e) {
            logger.error(e.getMessage(), e);
        }
        return mav;
    }

    /**
     * 城市分类保内系数(一二级保内分类系数对应表) bizType 2 保内 1 保外
     *
     * @param cityId
     * @param provinceId
     * @param servCategId
     * @param cityName
     * @return
     */
    @RequestMapping(value = "categoryInRatio")
    public ModelAndView categoryInRatio(@RequestParam(value = "priceType", defaultValue = "1") Integer priceType,
        @RequestParam(value = "cityId", defaultValue = "0") Integer cityId,
        @RequestParam(value = "provinceId", defaultValue = "0") Integer provinceId,
        @RequestParam(value = "servCategId", defaultValue = "0") Integer servCategId,
        @RequestParam(value = "cityName", defaultValue = "") String cityName) {
        return categoryRatio(priceType, cityId, provinceId, servCategId, ProductConsts.BIZ_TYPE_F, cityName);
    }

    /**
     * 城市分类保外系数(一二级保外分类系数对应表) 2 保内 1 保外
     *
     * @param cityId
     * @param provinceId
     * @param servCategId
     * @param cityName
     * @return
     */
    @RequestMapping(value = "categoryOutRatio")
    public ModelAndView categoryOutRatio(@RequestParam(value = "priceType", defaultValue = "1") Integer priceType,
        @RequestParam(value = "cityId", defaultValue = "0") Integer cityId,
        @RequestParam(value = "provinceId", defaultValue = "0") Integer provinceId,
        @RequestParam(value = "servCategId", defaultValue = "0") Integer servCategId,
        @RequestParam(value = "cityName", defaultValue = "") String cityName) {
        return categoryRatio(priceType, cityId, provinceId, servCategId, ProductConsts.BIZ_TYPE_C, cityName);
    }

    /**
     * 城市分类保外系数(一二级保外分类系数对应表) 2 保内 1 保外
     *
     * @param cityId
     * @param provinceId
     * @param servCategId
     * @param cityName
     * @return
     */
    @RequestMapping(value = "categoryProjectRatio")
    public ModelAndView categoryProjectRatio(@RequestParam(value = "priceType", defaultValue = "1") Integer priceType,
        @RequestParam(value = "cityId", defaultValue = "0") Integer cityId,
        @RequestParam(value = "provinceId", defaultValue = "0") Integer provinceId,
        @RequestParam(value = "servCategId", defaultValue = "0") Integer servCategId,
        @RequestParam(value = "cityName", defaultValue = "") String cityName) {
        return categoryRatio(priceType, cityId, provinceId, servCategId, ProductConsts.BIZ_TYPE_B, cityName);
    }

    /**
     * 城市分类系数(一二级分类系数对应表) 2 保内 1 保外
     *
     * @param cityId
     * @param provinceId
     * @param servCategId
     * @param bizType
     * @param cityName
     * @return
     */
    @SuppressWarnings("Duplicates")
    public ModelAndView categoryRatio(@RequestParam(value = "priceType", defaultValue = "1") Integer priceType,
        @RequestParam(value = "cityId", defaultValue = "0") Integer cityId,
        @RequestParam(value = "provinceId", defaultValue = "0") Integer provinceId,
        @RequestParam(value = "servCategId", defaultValue = "0") Integer servCategId,
        @RequestParam(value = "bizType", defaultValue = "1") Integer bizType,
        @RequestParam(value = "cityName", defaultValue = "") String cityName) {
        BaseCityRatioQuery query = new BaseCityRatioQuery();
        query.setCityId(cityId);
        query.setProvinceId(provinceId);
        query.setServCategId(servCategId);
        query.setBizType(bizType);
        query.setPriceType(priceType);

        ServCategory servCategoryQuery = new ServCategory();
        servCategoryQuery.setStatus(GlobalConsts.YES);
        List<ServCategory> servCategoryList = servCategoryService.listByQuery(servCategoryQuery);
        String servCategName = "";
        if (servCategId == 0) {
            if (servCategoryList != null && servCategoryList.size() > 0) {
                ServCategory servCategory = servCategoryList.get(0);
                query.setServCategId(servCategory.getCategId());
                servCategName = servCategory.getName();
            }
        } else {
            ServCategory servCategory = servCategoryService.findByKey(servCategId);
            servCategName = servCategory.getName();
        }

        query.setRatioType(BaseCityRatioTypeEnum.CITYCATEGONERATIO.getCode());
        List<BaseCityRatio> baseCityPriceLevelOneRatioVos = baseCityRatioService.listByQuery(query);
        query.setRatioType(BaseCityRatioTypeEnum.CITYCATEGTWORATIO.getCode());
        List<BaseCityRatio> baseCityPriceLevelTwoRatioVos = baseCityRatioService.listByQuery(query);

        List<BaseCategory> categTwos = servAssCategoryService.findCategoryTwoByServId(query.getServCategId());
        Map<Integer, List<BaseCategory>> map = categTwos.stream().collect(Collectors.groupingBy(BaseCategory::getParentId));
        Map<Integer, List<BaseCityCategoryRatioVo>> levelTwoRatioMap = new HashMap<>();
        for (Map.Entry<Integer, List<BaseCategory>> entry : map.entrySet()) {
            List<BaseCityCategoryRatioVo> resultList = new ArrayList<>();
            if (entry.getValue() != null) {
                for (BaseCategory baseCategory : entry.getValue()) {
                    BaseCityCategoryRatioVo baseCityPriceLevelTwoRatioVo = new BaseCityCategoryRatioVo();
                    baseCityPriceLevelTwoRatioVo.setCityId(cityId);
                    baseCityPriceLevelTwoRatioVo.setProvinceId(provinceId);
                    baseCityPriceLevelTwoRatioVo.setCategId(baseCategory.getCategId());
                    baseCityPriceLevelTwoRatioVo.setCategName(baseCategory.getName());
                    for (BaseCityRatio inner : baseCityPriceLevelTwoRatioVos) {
                        if (inner.getCategId().equals(baseCategory.getCategId())
                            && inner.getCategOneId().equals(baseCategory.getParentId())) {
                            baseCityPriceLevelTwoRatioVo.setRatio(inner.getRatio());
                            baseCityPriceLevelTwoRatioVo.setToBeEffectiveRatio(inner.getToBeEffectiveRatio());
                        }
                    }
                    resultList.add(baseCityPriceLevelTwoRatioVo);
                }
            }
            levelTwoRatioMap.put(entry.getKey(), resultList);
        }

        List<BaseCategory> categOnes = servAssCategoryService.findCategoryOneByServId(query.getServCategId());
        List<BaseCityCategoryRatioVo> constructVo = new ArrayList<>();
        for (BaseCategory baseCategory : categOnes) {
            BaseCityCategoryRatioVo baseCityPriceLevelOneRatioVo = new BaseCityCategoryRatioVo();
            baseCityPriceLevelOneRatioVo.setCategId(baseCategory.getCategId());
            baseCityPriceLevelOneRatioVo.setCategName(baseCategory.getName());
            constructVo.add(baseCityPriceLevelOneRatioVo);
        }

        for (BaseCityCategoryRatioVo baseCityPriceLevelOneRatioVo : constructVo) {
            for (BaseCityRatio inner : baseCityPriceLevelOneRatioVos) {
                if (baseCityPriceLevelOneRatioVo.getCategId().equals(inner.getCategOneId())) {
                    baseCityPriceLevelOneRatioVo.setRatio(inner.getRatio());
                    baseCityPriceLevelOneRatioVo.setToBeEffectiveRatio(inner.getToBeEffectiveRatio());
                }
            }
        }

        // 2代表保内 1代表保外
        ModelAndView mav = new ModelAndView("product/citypriceratio/citycategoryratio");;

        mav.addObject("servCategId", query.getServCategId());
        mav.addObject("cityId", cityId);
        mav.addObject("bizType", bizType);
        mav.addObject("priceType", priceType);
        mav.addObject("provinceId", provinceId);
        mav.addObject("cityName", cityName);
        mav.addObject("servCategName", servCategName);
        mav.addObject("categOnes", constructVo);
        mav.addObject("servCategoryList", servCategoryList);
        mav.addObject("map", levelTwoRatioMap);
        return mav;
    }

    /**
     * 设置保内/保外分类系数的详情页面
     *
     * @param cityId
     * @param provinceId
     * @param servCategId
     * @param categOneId
     * @param categOneName
     * @param bizType
     * @param priceType
     * @param cityName
     * @param servCategName
     * @return
     */
    @RequestMapping(value = "detail")
    @SuppressWarnings("Duplicates")
    public ModelAndView detail(@RequestParam(value = "cityId", defaultValue = "0") Integer cityId,
        @RequestParam(value = "provinceId", defaultValue = "0") Integer provinceId,
        @RequestParam(value = "servCategId", defaultValue = "0") Integer servCategId,
        @RequestParam(value = "categOneId", defaultValue = "0") Integer categOneId,
        @RequestParam(value = "categOneName", defaultValue = "0") String categOneName,
        @RequestParam(value = "bizType", defaultValue = "1") Integer bizType,
        @RequestParam(value = "priceType", defaultValue = "1") Integer priceType,
        @RequestParam(value = "cityName", defaultValue = "") String cityName,
        @RequestParam(value = "servCategName", defaultValue = "") String servCategName) {
        BaseCityRatioQuery query = new BaseCityRatioQuery();
        query.setCityId(cityId);
        query.setProvinceId(provinceId);
        query.setServCategId(servCategId);
        query.setBizType(bizType);
        query.setPriceType(priceType);

        if (servCategId == 0) {
            ServCategory servCategory = servCategoryService.findFirstOneByCategIdAsc();
            query.setServCategId(servCategory.getCategId());
        }

        String categOneValue = "";
        String categOneToBeEffectiveValue = "";
        query.setRatioType(BaseCityRatioTypeEnum.CITYCATEGONERATIO.getCode());
        query.setCategOneId(categOneId);
        List<BaseCityRatio> baseCityPriceRatioList = baseCityRatioService.listByQuery(query);
        if (baseCityPriceRatioList != null && baseCityPriceRatioList.size() > 0) {
            categOneValue = baseCityPriceRatioList.get(0).getRatio() == null ? "" : baseCityPriceRatioList.get(0).getRatio().toString();
            categOneToBeEffectiveValue = baseCityPriceRatioList.get(0).getToBeEffectiveRatio() == null ? ""
                : baseCityPriceRatioList.get(0).getToBeEffectiveRatio().toString();
        }

        query.setRatioType(BaseCityRatioTypeEnum.CITYCATEGTWORATIO.getCode());
        List<BaseCityRatio> baseCityPriceLevelTwoRatioVos = baseCityRatioService.listByQuery(query);
        List<BaseCategory> categTwos = servAssCategoryService.findCategoryTwoByServId(query.getServCategId());
        Map<Integer, List<BaseCategory>> map = categTwos.stream().collect(Collectors.groupingBy(BaseCategory::getParentId));

        List<BaseCityCategoryRatioVo> resultList = new ArrayList<>();
        if (map.get(categOneId) != null) {
            for (BaseCategory baseCategory : map.get(categOneId)) {
                BaseCityCategoryRatioVo baseCityPriceLevelTwoRatioVo = new BaseCityCategoryRatioVo();
                baseCityPriceLevelTwoRatioVo.setCityId(cityId);
                baseCityPriceLevelTwoRatioVo.setProvinceId(provinceId);
                baseCityPriceLevelTwoRatioVo.setCategId(baseCategory.getCategId());
                baseCityPriceLevelTwoRatioVo.setCategName(baseCategory.getName());
                for (BaseCityRatio inner : baseCityPriceLevelTwoRatioVos) {
                    if (inner.getCategId().equals(baseCategory.getCategId()) && inner.getCategOneId().equals(baseCategory.getParentId())) {
                        baseCityPriceLevelTwoRatioVo.setRatio(inner.getRatio());
                        baseCityPriceLevelTwoRatioVo.setToBeEffectiveRatio(inner.getToBeEffectiveRatio());
                    }
                }
                resultList.add(baseCityPriceLevelTwoRatioVo);
            }
        }

        ModelAndView mav = new ModelAndView("product/citypriceratio/citycategoryratiodetail");;

        mav.addObject("servCategId", servCategId);
        mav.addObject("cityId", cityId);
        mav.addObject("cityName", cityName);
        mav.addObject("provinceId", provinceId);
        mav.addObject("categOneId", categOneId);
        mav.addObject("bizType", bizType);
        mav.addObject("priceType", priceType);
        mav.addObject("categOneName", categOneName);
        mav.addObject("categOneValue", categOneValue);
        mav.addObject("categOneToBeEffectiveValue", categOneToBeEffectiveValue);
        mav.addObject("servCategName", servCategName);
        mav.addObject("levelTwoRatio", resultList);
        return mav;
    }

    @RequestMapping("cityRatio")
    public ModelAndView cityRatio(@RequestParam(value = "priceType", defaultValue = "0") int priceType,
        @RequestParam(value = "cityId", defaultValue = "0") int cityId,
        @RequestParam(value = "provinceId", defaultValue = "0") int provinceId) {
        BaseCityRatio baseCityRatioC =
            Optional
                .ofNullable(baseCityRatioService.findByRatioTypeAndCityAndCategAndBizType(priceType,
                    BaseCityRatioTypeEnum.CITYRATIO.getCode(), cityId, null, null, null, ProductConsts.BIZ_TYPE_C))
                .orElse(new BaseCityRatio());
        BaseCityRatio baseCityRatioF =
            Optional
                .ofNullable(baseCityRatioService.findByRatioTypeAndCityAndCategAndBizType(priceType,
                    BaseCityRatioTypeEnum.CITYRATIO.getCode(), cityId, null, null, null, ProductConsts.BIZ_TYPE_F))
                .orElse(new BaseCityRatio());
        BaseCityRatio baseCityRatioB =
            Optional
                .ofNullable(baseCityRatioService.findByRatioTypeAndCityAndCategAndBizType(priceType,
                    BaseCityRatioTypeEnum.CITYRATIO.getCode(), cityId, null, null, null, ProductConsts.BIZ_TYPE_B))
                .orElse(new BaseCityRatio());

        BaseCityRatio baseCityRatioM =Optional.ofNullable(baseCityRatioService.findByRatioTypeAndCityAndCategAndBizType(priceType,
                                BaseCityRatioTypeEnum.CITYMETER3RATIO.getCode(), cityId, null, null, null, null))
                        .orElse(new BaseCityRatio());

        BaseArea baseArea = areaCache.getArea(cityId);

        ModelAndView mav = new ModelAndView("product/citypriceratio/setcityratio");

        mav.addObject("cityRatioC", baseCityRatioC);
        mav.addObject("cityRatioF", baseCityRatioF);
        mav.addObject("cityRatioB", baseCityRatioB);
        mav.addObject("cityRatioM", baseCityRatioM);
        mav.addObject("cityId", cityId);
        mav.addObject("provinceId", provinceId);
        mav.addObject("cityName", baseArea == null ? "" : baseArea.getName());
        mav.addObject("priceType", priceType);
        return mav;
    }

    /**
     * 基础城市系数快速设置,跳转到城市选择页面
     *
     * @return
     */
    @RequestMapping("citySelectBatch")
    @SuppressWarnings("Duplicates")
    public ModelAndView citySelectBatch() {
        ModelAndView mav = new ModelAndView("product/citypriceratio/batch/_cityRatioBatch");
        // 1.加载 省--》城市
        List<BaseArea> provinces = baseAreaService.listByParentId(GlobalConsts.TOP_ID);
        // 加载城市
        AreaQuery cityQuery = new AreaQuery();
        cityQuery.setLevel(BaseAreaConsts.AREA_LEVEL_THREE);
        List<BaseArea> citys = baseAreaService.listByQuery(cityQuery);
        Map<Integer, List<BaseArea>> cityMap = new HashMap<>();
        if (!CollectionUtils.isEmpty(citys)) {
            cityMap = citys.stream().collect(Collectors.groupingBy(BaseArea::getParentId));
        }
        mav.addObject("provinces", provinces);
        mav.addObject("cityMap", cityMap);

        return mav;
    }

    /**
     * 基础城市系数快速设置,跳转到保外默认设置页面
     *
     * @return
     */
    @RequestMapping("cityBatchRatio")
    public ModelAndView cityBatchOutRatio(@RequestParam(value = "priceType", defaultValue = "1") Integer priceType) {
        ModelAndView mav = new ModelAndView("product/citypriceratio/batch/setCityBatchRatio");
        mav.addObject("priceType", priceType);
        return mav;
    }

    /**
     * 城市批量设置分类保外系数(一二级保外分类系数对应表)
     *
     * @param cityIdStr
     *            城市ID组合成的字符串
     * @param servCategId
     *            服务分类ID
     * @param bizType
     *            业务类型 1保外 2保内 3工程
     * @param priceType
     *            1销售价 2内部价
     * @return
     */
    @RequestMapping(value = "categoryRatioBatch")
    @SuppressWarnings("Duplicates")
    public ModelAndView categoryRatioBatch(@RequestParam(value = "cityIdStr", defaultValue = "") String cityIdStr,
        @RequestParam(value = "bizType", defaultValue = "1") Integer bizType,
        @RequestParam(value = "priceType", defaultValue = "1") Integer priceType,
        @RequestParam(value = "servCategId", defaultValue = "0") Integer servCategId) {
        ModelAndView mav = new ModelAndView("product/citypriceratio/batch/citybatchcategoryratio");
        ServCategory servCategoryQuery = new ServCategory();
        servCategoryQuery.setStatus(GlobalConsts.YES);
        List<ServCategory> servCategoryList = servCategoryService.listByQuery(servCategoryQuery);
        String servCategName = "";

        if (NumberUtil.isNullOrZero(servCategId)) {
            if (servCategoryList != null && servCategoryList.size() > 0) {
                ServCategory servCategory = servCategoryList.get(0);
                servCategId = servCategory.getCategId();
                servCategName = servCategory.getName();
            }
        } else {
            ServCategory servCategory = servCategoryService.findByKey(servCategId);
            servCategName = servCategory.getName();
        }

        List<BaseCategory> categTwos = servAssCategoryService.findCategoryTwoByServId(servCategId);
        Map<Integer, List<BaseCategory>> map = categTwos.stream().collect(Collectors.groupingBy(BaseCategory::getParentId));

        List<BaseCategory> categOnes = servAssCategoryService.findCategoryOneByServId(servCategId);

        mav.addObject("map", map);
        mav.addObject("categOnes", categOnes);
        mav.addObject("bizType", bizType);
        mav.addObject("priceType", priceType);
        mav.addObject("cityIdStr", cityIdStr);
        mav.addObject("servCategId", servCategId);
        mav.addObject("servCategName", servCategName);
        mav.addObject("servCategoryList", servCategoryList);
        return mav;
    }

    /**
     * 设置保内/保外/工程分类系数的详情页面
     *
     * @param cityIdStr
     *            城市ID集合
     * @param servCategId
     *            服务分类ID
     * @param categOneId
     *            一级产品分类ID
     * @param categOneName
     *            一级产品分类名称
     * @param bizType
     *            1保外 2 保内 3工程
     * @param priceType
     *            1销售价 2内部价
     * @param servCategName
     *            服务分类名称
     * @return
     */
    @RequestMapping(value = "toCategCityRatioBatch")
    @SuppressWarnings("Duplicates")
    public ModelAndView toCategCityRatioBatch(@RequestParam(value = "cityIdStr", defaultValue = "") String cityIdStr,
        @RequestParam(value = "servCategId", defaultValue = "0") int servCategId,
        @RequestParam(value = "categOneId", defaultValue = "0") int categOneId,
        @RequestParam(value = "categOneName", defaultValue = "0") String categOneName,
        @RequestParam(value = "bizType", defaultValue = "0") int bizType,
        @RequestParam(value = "priceType", defaultValue = "0") int priceType,
        @RequestParam(value = "servCategName", defaultValue = "") String servCategName) {

        if (servCategId == 0) {
            ServCategory servCategory = servCategoryService.findFirstOneByCategIdAsc();
            servCategId = servCategory.getCategId();
        }

        List<BaseCategory> categTwos = servAssCategoryService.findCategoryTwoByServId(servCategId);
        Map<Integer, List<BaseCategory>> map = categTwos.stream().collect(Collectors.groupingBy(BaseCategory::getParentId));

        ModelAndView mav = new ModelAndView("product/citypriceratio/batch/citybatchcategoryoutratiodetail");

        mav.addObject("servCategId", servCategId);
        mav.addObject("cityIdStr", cityIdStr);
        mav.addObject("categOneId", categOneId);
        mav.addObject("categTwos", map.get(categOneId));
        mav.addObject("bizType", bizType);
        mav.addObject("priceType", priceType);
        mav.addObject("categOneName", categOneName);
        mav.addObject("servCategName", servCategName);
        return mav;
    }
}
